#pragma once

#include "base/core/singleton.h"
#include "base/core/object_pool.h"
#include "Common/ServerDefine.h"
#include "Common/NetPack/NetPack.h"
#include "Common/Utility/Service.h"
#include "Common/Timer/ITimer.h"
#include "Common/AccountDefine.h"
#include "Common/MessageDispatch/MessageDispatch.h"
#include <unordered_map>
#include <string>
#include "Common/Utility/JsonUtility.h"

using namespace std;

class LoginService : public Service, public ManualSingleton < LoginService >
{
	friend class ManualSingleton < LoginService > ;
protected:
	typedef unordered_map<uint32_t, ISession*>  SESSION_MAP;
protected:
	uint32_t			m_groupId;
	uint16_t			m_outerPort;
	uint64_t			m_syncStateTick;
	char				m_listenIP[ADDRESS_IP_LENGTH];
	//char				m_outerIP[ADDRESS_IP_LENGTH];
	void*				m_listenHandle;
	
	uint32_t            m_connectFlag;

	IMessageDispatch   *m_pMessageDispatch;

	ServiceConnect		m_logServer;
	ServiceConnect		m_masterServer;
	ServiceConnect		m_accountDBServer;
	ServiceConnect		m_loginWebServer;

	string				m_strVesion;
	bool                m_tokenTimeCheck;
public:
	virtual bool Init(Net* net, const char* configFile)override;
	virtual void UnInit()override;
	virtual bool Update(uint64_t tick)override;
	virtual bool Quit() override;
	virtual bool HandleConsoleCmd(const char* cmd)override;
	virtual bool TrueClientMessage(RECV_PACKAGE& package);
	virtual IMessageDispatch *GetServiceMessageDispatch() override;

	uint32_t GetSessionId();
	bool  IsConnectLoginWeb(){ return m_loginWebServer.session != nullptr; }

	bool  TokenTimeCheck(){ return m_tokenTimeCheck; }

	bool  SendDataToClient(ISession* session, uint16_t protocolCmd, ProtoBufBase* buf);
	bool  SendLogToLogServer(JsonObject& jsons);
	bool  SendDataToMaster(uint16_t protocolCmd, ProtoBufBase* buf);
	bool  IsConnectMaster();
	bool  SendDataToAccountDB(uint16_t module, uint16_t protocolCmd, ProtoBufBase* buf);
	bool  SendDataToLoginWeb(uint16_t protocolCmd, ProtoBufBase* buf);

	static bool _OnAcceptClient(ISession* session, void* context);
	static bool _OnCloseClient(ISession* session, void* context, CloseFlag flag);
	static bool _OnCloseServer(ISession* session, void* context, CloseFlag flag);

	static bool _OnConnectMaster(ISession* session, void* context, bool success);
	static bool _OnConnectLogServer(ISession* session, void* context, bool success);
	static bool _OnConnectAccountDBServer(ISession* session, void* context, bool success);
	static bool _OnConnectLoginWeb(ISession* session, void* context, bool success);

	string GetVesion();

protected:
	bool  _CheckQuittingComplete();
	bool  _LoadConfig(const char* config_file);
	bool  _ListenAddress();
	bool  _ProcessConnection();
	bool  _SyncServiceState(uint64_t tick);
	void  _SetConnectFlag(ServiceConnectFlag flag, bool open);

protected:
	LoginService();
	virtual ~LoginService()override;
};

#define g_MakeLoginService() (LoginService::Instance())
#define g_GetLoginService()  (LoginService::GetInstance())
#define g_DelLoginService()  (LoginService::Destroy())
